package com.devenv.service;

import com.devenv.entity.SystemConfig;
import com.devenv.repository.SystemConfigRepository;
import com.devenv.dto.SystemConfigDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 系统配置服务实现
 * <p>
 * 提供系统配置的完整管理功能，包括增删改查、缓存管理等
 * </p>
 * 
 * @author DevEnv OpenSource Team
 * @version 1.0.0
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SystemConfigService {

    private final SystemConfigRepository systemConfigRepository;

    /**
     * 根据ID查询系统配置
     */
    @Cacheable(value = "systemConfig", key = "#id")
    public Optional<SystemConfig> findById(Long id) {
        log.debug("查询系统配置，ID: {}", id);
        return systemConfigRepository.findById(id);
    }

    /**
     * 根据配置键查询系统配置
     */
    @Cacheable(value = "systemConfig", key = "'key:' + #configKey")
    public Optional<SystemConfig> findByKey(String configKey) {
        log.debug("根据配置键查询系统配置: {}", configKey);
        return systemConfigRepository.findByConfigKey(configKey);
    }

    /**
     * 获取配置值
     */
    @Cacheable(value = "systemConfigValue", key = "#configKey")
    public String getConfigValue(String configKey) {
        log.debug("获取配置值: {}", configKey);
        return systemConfigRepository.findByConfigKey(configKey)
                .map(SystemConfig::getConfigValue)
                .orElse(null);
    }

    /**
     * 获取配置值，如果不存在返回默认值
     */
    public String getConfigValue(String configKey, String defaultValue) {
        String value = getConfigValue(configKey);
        return value != null ? value : defaultValue;
    }

    /**
     * 获取布尔配置值
     */
    public Boolean getBooleanConfigValue(String configKey) {
        String value = getConfigValue(configKey);
        return value != null ? Boolean.parseBoolean(value) : null;
    }

    /**
     * 获取布尔配置值，如果不存在返回默认值
     */
    public Boolean getBooleanConfigValue(String configKey, Boolean defaultValue) {
        Boolean value = getBooleanConfigValue(configKey);
        return value != null ? value : defaultValue;
    }

    /**
     * 获取整数配置值
     */
    public Integer getIntegerConfigValue(String configKey) {
        String value = getConfigValue(configKey);
        if (value != null) {
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                log.warn("配置值不是有效的整数: {} = {}", configKey, value);
            }
        }
        return null;
    }

    /**
     * 获取整数配置值，如果不存在返回默认值
     */
    public Integer getIntegerConfigValue(String configKey, Integer defaultValue) {
        Integer value = getIntegerConfigValue(configKey);
        return value != null ? value : defaultValue;
    }

    /**
     * 获取所有公开配置
     */
    @Cacheable(value = "publicConfigs")
    public List<SystemConfig> findAllPublicConfigs() {
        log.debug("查询所有公开配置");
        return systemConfigRepository.findByIsPublicTrueOrderByConfigGroupAscSortOrderAsc();
    }

    /**
     * 获取所有公开配置的Map
     */
    public Map<String, String> getPublicConfigMap() {
        return findAllPublicConfigs().stream()
                .collect(Collectors.toMap(
                        SystemConfig::getConfigKey,
                        SystemConfig::getConfigValue
                ));
    }

    /**
     * 获取所有系统配置
     */
    @Cacheable(value = "systemConfigs")
    public List<SystemConfig> findAllSystemConfigs() {
        log.debug("查询所有系统配置");
        return systemConfigRepository.findByIsSystemTrueOrderByConfigGroupAscSortOrderAsc();
    }

    /**
     * 分页查询系统配置
     */
    public Page<SystemConfig> findAll(Pageable pageable) {
        log.debug("分页查询系统配置，页码: {}, 大小: {}", pageable.getPageNumber(), pageable.getPageSize());
        return systemConfigRepository.findAll(pageable);
    }

    /**
     * 根据关键字搜索配置
     */
    public Page<SystemConfig> searchConfigs(String keyword, Pageable pageable) {
        log.debug("搜索系统配置，关键字: {}", keyword);
        return systemConfigRepository.findByConfigKeyContainingOrDescriptionContaining(
                keyword, keyword, pageable);
    }

    /**
     * 创建系统配置
     */
    @Transactional
    @CacheEvict(value = {"systemConfig", "systemConfigValue", "publicConfigs", "systemConfigs"}, allEntries = true)
    public SystemConfig createConfig(SystemConfigDTO dto) {
        log.info("创建系统配置: {}", dto.getConfigKey());
        
        // 检查配置键是否已存在
        if (systemConfigRepository.findByConfigKey(dto.getConfigKey()).isPresent()) {
            throw new IllegalArgumentException("配置键已存在: " + dto.getConfigKey());
        }

        SystemConfig config = new SystemConfig();
        config.setConfigKey(dto.getConfigKey());
        config.setConfigValue(dto.getConfigValue());
        config.setDescription(dto.getDescription());
        config.setIsSystem(dto.getIsSystem() != null ? dto.getIsSystem() : false);
        config.setIsPublic(dto.getIsPublic() != null ? dto.getIsPublic() : false);

        return systemConfigRepository.save(config);
    }

    /**
     * 更新系统配置
     */
    @Transactional
    @Caching(
        put = {@CachePut(value = "systemConfig", key = "#id")},
        evict = {
            @CacheEvict(value = "systemConfigValue", key = "#dto.configKey"),
            @CacheEvict(value = "publicConfigs", allEntries = true),
            @CacheEvict(value = "systemConfigs", allEntries = true)
        }
    )
    public SystemConfig updateConfig(Long id, SystemConfigDTO dto) {
        log.info("更新系统配置，ID: {}", id);
        
        SystemConfig config = systemConfigRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("系统配置不存在，ID: " + id));

        config.setConfigValue(dto.getConfigValue());
        config.setDescription(dto.getDescription());
        
        // 系统配置的类型属性通常不允许修改
        if (!config.getIsSystem()) {
            config.setIsPublic(dto.getIsPublic() != null ? dto.getIsPublic() : config.getIsPublic());
        }

        return systemConfigRepository.save(config);
    }

    /**
     * 更新配置值
     */
    @Transactional
    @Caching(
        evict = {
            @CacheEvict(value = "systemConfig", key = "'key:' + #configKey"),
            @CacheEvict(value = "systemConfigValue", key = "#configKey"),
            @CacheEvict(value = "publicConfigs", allEntries = true),
            @CacheEvict(value = "systemConfigs", allEntries = true)
        }
    )
    public boolean updateConfigValue(String configKey, String configValue) {
        log.info("更新配置值: {} = {}", configKey, configValue);
        
        Optional<SystemConfig> configOpt = systemConfigRepository.findByConfigKey(configKey);
        if (configOpt.isPresent()) {
            SystemConfig config = configOpt.get();
            config.setConfigValue(configValue);
            systemConfigRepository.save(config);
            return true;
        }
        return false;
    }

    /**
     * 删除系统配置
     */
    @Transactional
    @Caching(
        evict = {
            @CacheEvict(value = "systemConfig", key = "#id"),
            @CacheEvict(value = "publicConfigs", allEntries = true),
            @CacheEvict(value = "systemConfigs", allEntries = true)
        }
    )
    public boolean deleteConfig(Long id) {
        log.info("删除系统配置，ID: {}", id);
        
        Optional<SystemConfig> configOpt = systemConfigRepository.findById(id);
        if (configOpt.isPresent()) {
            SystemConfig config = configOpt.get();
            
            // 系统配置不允许删除
            if (config.getIsSystem()) {
                throw new IllegalArgumentException("系统配置不允许删除: " + config.getConfigKey());
            }
            
            // 先清除特定的缓存
            evictConfigCache(config.getConfigKey());
            systemConfigRepository.deleteById(id);
            return true;
        }
        return false;
    }

    /**
     * 初始化默认配置
     */
    @Transactional
    public void initializeDefaultConfigs() {
        log.info("初始化默认系统配置");
        
        createConfigIfNotExists("system.name", "DevEnv开源版", "系统名称", true, true);
        createConfigIfNotExists("system.version", "1.0.0", "系统版本", true, true);
        createConfigIfNotExists("system.description", "DevEnv开源软件管理平台", "系统描述", true, true);
        createConfigIfNotExists("upload.max.size", "10485760", "文件上传最大大小(字节)", true, false);
        createConfigIfNotExists("cache.ttl", "3600", "缓存过期时间(秒)", true, false);
        createConfigIfNotExists("page.size.default", "20", "默认分页大小", true, true);
        createConfigIfNotExists("page.size.max", "100", "最大分页大小", true, true);
        createConfigIfNotExists("registration.enabled", "true", "是否允许用户注册", true, true);
        createConfigIfNotExists("maintenance.mode", "false", "维护模式", true, false);
    }

    /**
     * 创建配置（如果不存在）
     */
    private void createConfigIfNotExists(String key, String value, String description, 
                                       boolean isSystem, boolean isPublic) {
        if (systemConfigRepository.findByConfigKey(key).isEmpty()) {
            SystemConfig config = new SystemConfig();
            config.setConfigKey(key);
            config.setConfigValue(value);
            config.setDescription(description);
            config.setIsSystem(isSystem);
            config.setIsPublic(isPublic);
            systemConfigRepository.save(config);
            log.debug("创建默认配置: {} = {}", key, value);
        }
    }

    /**
     * 清除配置缓存
     */
    @CacheEvict(value = "systemConfigValue", key = "#configKey")
    public void evictConfigCache(String configKey) {
        log.debug("清除配置缓存: {}", configKey);
    }

    /**
     * 清除所有配置缓存
     */
    @CacheEvict(value = {"systemConfig", "systemConfigValue", "publicConfigs", "systemConfigs"}, allEntries = true)
    public void evictAllConfigCache() {
        log.info("清除所有配置缓存");
    }

    /**
     * 检查系统是否处于维护模式
     */
    public boolean isMaintenanceMode() {
        return getBooleanConfigValue("maintenance.mode", false);
    }

    /**
     * 检查是否允许用户注册
     */
    public boolean isRegistrationEnabled() {
        return getBooleanConfigValue("registration.enabled", true);
    }

    /**
     * 获取默认分页大小
     */
    public int getDefaultPageSize() {
        return getIntegerConfigValue("page.size.default", 20);
    }

    /**
     * 获取最大分页大小
     */
    public int getMaxPageSize() {
        return getIntegerConfigValue("page.size.max", 100);
    }
}
